Skip to main content

22.03.07 - Declaring Types and Classes

Type Declarations

New name for an existing type can be defined using a type declaration

type String = [Char]

Type declarations can be used to make other types easier to read

Like function definitions, type declarations can also have parameters:

type Pair a = (a,a)

Type declarations can be nested, but never recursive

Data Declarations

New type can be defined by specifying its values using a data declaration

data Bool = False | True
  • The two values are called the constructors
  • Type and constructor names must always begin with an upper-case letter
  • Data declarations are similar to context free grammars. The former specifies the values of a type, the latter the sentences of a language

Values of new types can be used in the same ways as those of built in types The constructors in a data declaration can also have parameters

  • Shape has values of the form Circle r where r is a float, and Rect x y where x and y are floats
  • Circle and Rect can be viewed as functions that construct values of type shape
Circle :: Float -> Shape
Rect :: Float -> Float -> Shape

Data declarations can also have parameters

Recursive Types

New types can be declared in terms of themselves:

data Nat = Zero | Succ Nat
  • A value of type Nat is either Zero or of the form Succ n where n :: Nat.
  • Nat is natural numbers, where Zero represents 0 and Succ represents the successor function 1+. (Bit like proof with TIM S(S(S(0))))
  • Using recursion is easier to define functions that convert between values of type Nat and Int
  • Using recursion the function add can be defined without the need for conversions

Can add two natural numbers by converting them to integers, adding, then converting them back. However using recursion the function can be defined without the need for conversions

Arithmetic Expressions

Simple form of expressions built up from integers using addition and multiplication Three constructors have types:

Val :: Int -> Expr
Add :: Expr -> Expr -> Expr
Mul :: Expr -> Expr -> Expr

Many functions on expressions can be defined by replacing the constructors by other functions using a suitable fold function. E.g: eval = folde id (+) (*)